class LyricAudioPlayer {
  constructor(config = {}) {
    // 默认配置
    this.defaultConfig = {
      audioElement: null,
      audioUrl: null,
      showCover: true,
      showMetadata: true,
      showLyrics: false,
      showPlaylist: true,
      playlistPosition: 'right',
      repeatMode: 'none',
      shuffle: false,
      mode: 'fixed',
      position: {
        fixed: { bottom: '20px', left: '50%', transform: 'translateX(-50%)' },
        floating: { top: '100px', left: '100px' }
      },
      draggable: true,
      theme: {
        variables: {
          '--primary-color': '#2c3e50',
          '--secondary-color': '#ecf0f1',
          '--progress-height': '5px',
          '--border-radius': '8px'
        },
        customClass: ''
      },
      defaultCover: '',
      cacheStrategy: {
        enabled: true,
        ttl: 3600,
        maxSize: 100
      }
    };

    // 合并配置
    this.config = { ...this.defaultConfig, ...config };

    // 初始化核心组件
    this.audio = this.config.audioElement || this._createAudioElement();
    this.playlist = [];
    this.currentTrackIndex = -1;
    this.shuffleList = [];
    this.isDragging = false;
    this.dragStartPos = { x: 0, y: 0 };
    this.elementOffset = { x: 0, y: 0 };
    this.cache = new Map();
    this.animationFrameId = null;

    // 初始化流程
    this._init();
  }

  /*********************
   * 核心初始化方法
   *********************/
  _init() {
    this._createDOMStructure();
    this._applyTheme();
    this._bindEvents();
    this._setupAudioAnalyser();
    this._loadInitialAudio();
    this._setupCache();
    this._setupDrag();
    this._setupKeyboardControls();
  }

  /*********************
   * DOM操作相关方法
   *********************/
  _createDOMStructure() {
    this.container = document.createElement('div');
    this.container.className = `lap-container ${this.config.theme.customClass}`;
    this.container.innerHTML = `
      <div class="lap-header">
        <div class="lap-controls-top">
          <button class="lap-minimize">−</button>
          <button class="lap-close">×</button>
        </div>
      </div>
      <div class="lap-main">
        <div class="lap-cover-container">
          <div class="lap-cover-loader"></div>
          <img class="lap-cover-image" src="${this.config.defaultCover}">
          <canvas class="lap-visualizer"></canvas>
        </div>
        <div class="lap-info-container">
          <div class="lap-title">No Title</div>
          <div class="lap-artist">Unknown Artist</div>
          <div class="lap-progress-container">
            <input type="range" class="lap-progress" min="0" max="100">
            <div class="lap-time-display">
              <span class="lap-current-time">0:00</span>
              <span class="lap-duration">0:00</span>
            </div>
          </div>
          <div class="lap-controls">
            <button class="lap-prev">⏮</button>
            <button class="lap-play-pause">▶</button>
            <button class="lap-next">⏭</button>
            <input type="range" class="lap-volume" min="0" max="1" step="0.1" value="1">
          </div>
        </div>
        <div class="lap-lyrics-container"></div>
      </div>
      <div class="lap-playlist"></div>
    `;
    document.body.appendChild(this.container);
  }

  /*********************
   * 音频控制相关方法
   *********************/
  play() {
    return this.audio.play().catch(err => {
      this._dispatchEvent('error', { error: err });
    });
  }

  pause() {
    this.audio.pause();
  }

  togglePlay() {
    this.audio.paused ? this.play() : this.pause();
  }

  seekTo(time) {
    this.audio.currentTime = Math.max(0, Math.min(time, this.audio.duration));
  }

  /*********************
   * 播放列表管理
   *********************/
  loadPlaylist(playlist) {
    this.playlist = playlist.map(track => ({
      ...track,
      lyrics: this._parseLyrics(track.lyrics)
    }));
    this._renderPlaylist();
    this.playTrack(0);
  }

  playTrack(index) {
    if (index < 0 || index >= this.playlist.length) return;
    
    this.currentTrackIndex = index;
    const track = this.playlist[index];
    
    this.audio.src = track.audioUrl;
    this._updateMetadata(track);
    this._renderLyrics(track.lyrics);
    this.play();
  }

  /*********************
   * 可视化与效果
   *********************/
  _setupAudioAnalyser() {
    const ctx = new (window.AudioContext || window.webkitAudioContext)();
    this.analyser = ctx.createAnalyser();
    const source = ctx.createMediaElementSource(this.audio);
    source.connect(this.analyser);
    this.analyser.connect(ctx.destination);
    this.analyser.fftSize = 256;

    this._startVisualization();
  }

  _startVisualization() {
    const bufferLength = this.analyser.frequencyBinCount;
    const dataArray = new Uint8Array(bufferLength);
    const canvas = this.container.querySelector('.lap-visualizer');
    const ctx = canvas.getContext('2d');

    const draw = () => {
      this.analyser.getByteFrequencyData(dataArray);
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // 绘制频谱柱
      const barWidth = (canvas.width / bufferLength) * 2.5;
      let x = 0;
      for (let i = 0; i < bufferLength; i++) {
        const barHeight = dataArray[i] / 2;
        ctx.fillStyle = `hsl(${i * 2}, 100%, 50%)`;
        ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight);
        x += barWidth + 1;
      }

      this.animationFrameId = requestAnimationFrame(draw);
    };

    draw();
  }

  /*********************
   * 工具方法
   *********************/
  _parseLyrics(lyrics) {
    return lyrics.split('\n').map(line => {
      const match = line.match(/\[(\d+):(\d+\.\d+)\](.*)/);
      return match ? {
        time: parseInt(match[1]) * 60 + parseFloat(match[2]),
        text: match[3].trim()
      } : null;
    }).filter(Boolean).sort((a, b) => a.time - b.time);
  }

  _dispatchEvent(name, detail) {
    const event = new CustomEvent(`lap:${name}`, { detail });
    this.container.dispatchEvent(event);
  }

  /*********************
   * 生命周期管理
   *********************/
  destroy() {
    cancelAnimationFrame(this.animationFrameId);
    this.audio.pause();
    this.audio.removeAttribute('src');
    this.audio.load();
    this.container.remove();
  }
}

// 模块导出
if (typeof module !== 'undefined' && module.exports) {
  module.exports = LyricAudioPlayer;
} else {
  window.LyricAudioPlayer = LyricAudioPlayer;
}